#include <stdio.h> // perror()/printf()
#include <sys/types.h> // pid_t
#include <wait.h>  // waitpid()
#include <stdlib.h> // exit()
#include <unistd.h> // pipe()/fork()/close()/read()/write()
#include <string.h> // strlen()

int main(int argc, char const *argv[])
{
    
    // 创建管道
    int pipedes[2];
    int pipe_r = pipe(pipedes);
    // 如果创建失败，提示并退出
    if (pipe_r == -1)
    {
        perror("创建管道失败");
        exit(EXIT_FAILURE);
    }

    // 创建子进程
    pid_t pid = fork();
    if (pid == -1) // 创建进程失败，提示并退出
    {
        perror("创建子进程失败");
        exit(EXIT_FAILURE);
    }
    else if (pid == 0) // 子进程
    {
        // 关闭子进程中管道写（只读数据）
        close(pipedes[1]);

        printf("子进程准备读取管道数据 \n");

        
        // 不断读取管道中的数据，直到管道两端的写流都关闭才会结束，
        // 否则当没有数据可读时会一直等待
        char *buf[5];
        ssize_t read_bytes;
        while ((read_bytes=read(pipedes[0], buf, 5)) > 0)
        {
            // 将读取数据写到标准输出
            write(STDOUT_FILENO, buf, read_bytes);
        }

        // 输出换行
        write(STDOUT_FILENO, "\n", 1);

        // 关闭子进程中管道的读
        close(pipedes[0]);

        // 退出子进程
        _exit(EXIT_SUCCESS);
    }
    else // 父进程
    {
        // 关闭父进程端管道的读
        close(pipedes[0]);

        // 提示
        printf("父进程准备向管道写入数据 \n");
        
        // 向管道写入数据
        char *msg = "atguigu.com";
        write(pipedes[1], msg, strlen(msg));
        
        // 关闭父进程端管道的写
        // close(pipedes[1]);

        // 等待子进程结束，父进程才退出
        waitpid(pid, NULL, 0);

        // 成功退出父进程
        exit(EXIT_SUCCESS);
    }
}